PROFDINFO.COM

Votre enseignant d'informatique en ligne

Section 2 - Environnement

Retour à la page du cours

La section 2 vous présentera la notion d'environnement, incluant les variables et les fichiers de configuration. On y verra également les alias, qui ne font pas officiellement partie de l'environnement mais qui sont souvent définis dans les fichiers de configuration.

2.1 - Variables d'environnement

2.2 - Les alias

2.3 - Les fichiers de configuration

2.1 - Variables d'environnement

 

Les variables d'environnement sous Linux contiennent des informations utiles que plusieurs logiciels peuvent aller chercher (ou modifier).

Pour voir l'ensemble des variables d'environnement qui sont définies (et leurs valeurs), on peut utiliser la commande env. Comme la sortie est généralement assez longue, env | less est une bonne idée. On peut aussi aller filtrer la sortie avec grep, qui n'affiche que les lignes contenant un certain mot, en faisant par exemple env | grep PATH.

Remarquez que par convention, les variables ont toujours un nom en majuscules. Elles doivent avoir un nom unique (mais comme pour tout le reste, la casse compte!).

Quelques variables d'environnement couramment utilisées:

  • USERNAME
  • PATH
  • SHELL
  • HOME
  • PWD
  • OLDPWD
  • PS1

Il en existe beaucoup d'autres, certaines sont propres à une distribution et ne seront pas nécessairement vues partout.

On peut faire afficher le contenu d'une variable en faisant echo $VARIABLE, par exemple echo $PATH. Il ne faut pas confondre avec echo PATH, qui ne fait que répéter le mot "PATH". Le "$" préfixant le nom de la variable demande à Linux de substituer la variable par son contenu avant d'exécuter la commande. Ceci fonctionnera avec n'importe quelle commande, pas uniquement echo.

On peut changer le contenu d'une variable simplement en faisant VARIABLE=valeur. Si VARIABLE existait, son contenu sera écrasé par valeur. Sinon, elle sera créée sur le champ.

Lorsque l'on crée une variable, elle ne fait pas partie de l'environnement. La différence entre une variable "ordinaire" (on l'appellera souvent "variable locale") et une variable d'environnement est au niveau de sa portée. Lorsqu'un nouveau shell est démarré à partir du premier, les variables d'environnement seront passées au shell enfant; les variables locales ne le seront pas. Quelques façons de démarrer un nouveau shell à partir du shell courant:

  • Utiliser la commande su (switch user) pour prendre momentanément l'identité de quelqu'un d'autre (jusqu'à ce qu'on tape exit pour redevenir nous-mêmes).
  • Démarrer un script ou un programme - en effet, un programme est toujours démarré dans un nouveau shell, enfant du shell courant, question de limiter les dégâts en cas de "plantage"
    • Il arrive qu'on veuille forcer le programme à s'exécuter dans le shell courant plutôt que dans un shell enfant (c'est le cas par exemple des scripts qui mettent en place l'environnement). Dans ce cas, on peut utiliser la commande source. Par exemple, si je fais source programme, je demande à programme de s'exécuter dans mon shell courant. On peut faire la même chose en utilisant le "." (point), comme ceci: . programme (il ne faut pas confondre ce point et celui qui représente le répertoire courant. Le point équivalent à la commande source est justement utilisé comme une commande, c'est-à-dire suivi d'un espace et d'un paramètre).
  • Appeler directement bash (ou un autre shell si vous en avez d'installés), ce qui en créera une nouvelle instance (jusqu'à ce qu'on tape exit pour redevenir nous-mêmes).

Notez que l'utilisation de sudo -i (pour devenir root) n'est pas régie par les mêmes règles et l'environnement de l'appelant n'est pas hérité lors de son utilisation.

Les variables locales sont généralement utilisées en scripting (on y reviendra dans un cours subséquent). Les variables d'environnement font partie de l'OS.

Pour envoyer une variable locale dans l'environnement (c'est la façon de créer une variable d'envrionnement), il suffit d'utiliser la commande export comme ceci: export VARIABLE. On peut également exporter une variable et lui donner une valeur en une seule commande, ainsi: export VARIABLE=valeur.

On peut détruire une variable, locale ou d'environnement, simplement en faisant unset VARIABLE.

La durée de vie d'une variable, qu'elle soit dans l'environnement ou non, est la durée de vie du shell dans lequel elle a été définie. Aucune variable n'est éternelle et toutes les variables sont perdues lorsqu'on se déconnecte du système. Pour qu'une variable soit vue comme "permanente", il faut ajouter sa définition à un fichier de configuration.

Retour à la table des matières de la section

2.1.1 - Quelques expérimentations

Indiquez la (ou les) commande(s) nécessaire(s) pour réaliser les opérations suivantes:

  • Créer une variable locale appelée GEORGES contenant la valeur georges.

 

  • Créer une variable d'environnement appelée GEORGES_ENV contenant aussi la valeur georges.

 

  • Démarrer un nouveau shell à partir du shell courant.

 

  • Vérifier la présence de la variable GEORGES dans ce nouveau shell.

 

  • Vérifier la présence de la variable GEORGES_ENV dans ce nouveau shell.

 

  • Créer une variable d'environnement appelée ROGER_ENV contenant la valeur roger.

 

  • Sortir du shell courant pour revenir au shell parent.

 

  • Vérifier la présence de la variable ROGER_ENV dans ce shell

 

  • Détruire la variable GEORGES_ENV.

 

 

  • Changer le contenu de la variable HOME pour qu'elle contienne allo

 

  • Se déplacer dans le répertoire /etc

 

  • Revenir à votre répertoire maison avec la commande la plus courte possible

 

  • Changer le contenu de la variable PWD pour qu'elle contienne patate

 

  • Changer le contenu de la variable OLDPWD pour qu'elle contienne vieille/patate

 

 

  • Remettre en place le contenu correct de la variable HOME

 

 

  • Créer un fichier envir dans votre répertoire maison, contenant la liste de toutes les variables d'environnement et leur contenu.

 

  • Afficher à l'écran le contenu de ce fichier.

 

Retour à la table des matières de la section

2.1.2 - La variable PATH

La variable PATH fait partie de l'environnement et a un usage important: celui de trouver les exécutables lorsqu'on tape son nom dans le shell.

Son contenu ressemble à quelque chose comme:

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

On remarque qu'il s'agit de chemins de répertoires séparés par des ":".

Son utilité est similaire à son homonyme dans le système Windows: lorsque vous tapez le nom d'une commande, d'un script ou d'un programme, Linux parcourt ces répertoires, dans l'ordre, à la recherche de l'exécutable correspondant. Lorsqu'il le trouve, il l'exécute. S'il ne le trouve pas après avoir parcouru tous les répertoires listés dans PATH, il affiche un message d'erreur du genre "commande introuvable".

La différence majeure entre Windows et Linux sur ce point est que Windows ira toujours voir en plus dans le répertoire courant à la recherche de l'exécutable demandé. Linux ne le fait pas. En conséquence, si vous tentez d'exécuter un programme qui ne se trouve pas dans votre PATH, le fait de vous déplacer dans le répertoire approprié ne changera rien, Linux ne le trouvera pas plus. Vous devrez alors donner le chemin complet vers l'exécutable. Par contre, vous pouvez vous en tirer aisément si vous êtes dans le bon répertoire, puisque donner un chemin relatif est tout aussi acceptable. Vous pourrez donc faire quelque chose comme ./programme pour demander à bash d'exécuter programme se trouvant dans votre répertoire courant. Il faut faire bien attention de ne pas confondre ./programme et . programme, deux commandes à l'effet bien différent!

La commande which permet de savoir quel exécutable est lancé lorsque vous tapez son nom - autrement dit, dans quel des répertoires listés dans PATH Linux trouve-t-il le programme voulu. Par exemple which ls affiche /bin/ls. Quand vous tapez ls, c'est le programme ls qui se trouve dans /bin qui est exécuté. Si jamais vous placiez un exécutable aussi appelé ls dans un des répertoires précédant /bin dans PATH (par exemple dans /usr/sbin), c'est celui-ci qui sera donc exécuté.

Pour modifier la variable d'environnement PATH, on peut faire comme pour toute autre variable. Toutefois, on préférera toujours ajouter à la liste des répertoires plutôt que de remplacer cette liste. Pour ajouter quelque chose au PATH (ou à toute autre variable en fait), on peut profiter de la substitution qui est faite par bash lorsqu'on utilise le "$". En effet, pour ajouter le répertoire /home/georges dans le PATH, on fera: PATH=$PATH:/home/georges.

Une des choses que l'on fera couramment, pour se simplifier la vie, sera d'ajouter le répertoire courant au PATH en faisant PATH=$PATH:. ou encore PATH=.:$PATH (quelle sera la différence entre ces deux commandes?).

Retour à la table des matières de la section

2.2 - Les alias

Un alias est simplement un autre nom pour une commande ou un programme. Un alias peut donner un nom simple à une commande complexe (avec différentes switches et même paramètres). Un alias peut même remplacer un groupe de plusieurs commandes, bien que ça soit rarement utilisé.

On peut voir les différents alias qui sont en place sur notre système simplement en tapant la commande alias. Vous remarquerez qu'il n'en existe qu'un, "ls", qui est un alias pour "ls --color=auto". La switche --color=auto est celle qui met des couleurs dans la sortie de ls. L'alias "ls" (portant le même nom que la commande, c'est très possible et même courant) nous assure qu'à chaque fois qu'on tape "ls", on exécutera en réalité "ls --color=auto" (ce qui serait plutôt fatiguant à faire explicitement à chaque fois!).

On peut créer un alias en faisant simplement alias nom='commande', où "nom" est le nom donné à l'alias et "commande" est la commande qu'il exécutera, aussi complexe qu'elle puisse être. Remarquez que la commande doit être placée entre 'apostrophes' et qu'il n'y a pas d'espaces de part et d'autre du "=".

Par exemple, on pourrait vouloir donner une confirmation à chaque fois qu'on tente d'effacer un fichier, pour se protéger des gaffes éventuelles. La commande rm a une switche -i qui sert justement à ça. Par contre, on ne peut pas s'attendre à ce qu'un usager fasse rm -i fichier à chaque fois qu'il veut effacer un fichier. On fera donc souvent un alias appelé lui aussi rm, qui pointera vers rm -i, ainsi: alias rm='rm -i'. À partir de maintenant, on devra confirmer chaque suppression. Remarquez que la même switche existe pour cp et mv, nous demandant de confirmer si notre copie ou déplacement écrase un fichier déjà existant.

On peut détruire un alias en faisant unalias nom (par exemple unalias rm).

On peut contourner un alias (forcer bash à utiliser la commande "pure" plutôt que l'alias pour cette fois-ci) en faisant \commande. Par exemple, si je fais \ls j'utilise la "vraie" commande ls et non pas son alias (notez la disparition des jolies couleurs). L'alias n'est pas détruit, il a juste été contourné pour cette fois-ci.

Point important: les alias ne sont pas exportables et ne peuvent pas faire partie de l'environnement. Ils ne sont jamais hérités à un shell enfant et il nous faudra donc les redéfinir au besoin dans ce shell enfant.

Leur durée de vie est la même que celle des variables. Si on veut qu'un alias soit toujours créé lorsqu'on se logue, il faudra ajouter sa définition à un des fichiers de configuration.

Retour à la table des matières de la section

2.3 - Les fichiers de configuration

Il existe deux grandes catégories de fichiers de configuration: ceux qui affectent tous les usagers sur le système (normalement placés dans le répertoire /etc) et les fichiers propres à un usager précis (normalement placés dans son répertoire maison ~).

Il existe également deux façons de se connecter à un système Linux: le mode "login shell" (le mode standard qui consiste à se connecter au serveur via notre login et mot de passe à partir d'une page d'ouverture de session) et le mode "interactif" (le mode qu'on utilise lorsque l'on fait un su pour changer d'identité). Certains fichiers de configuration sont lus lorsque l'on utilise un des deux modes, d'autres fichiers sont lus lorsque l'on utilise l'autre mode.

Les fichiers exacts utilisés et leur contenu pourra varier grandement d'une distribution à l'autre. Toutefois il existe certaines normes fixes.

Retour à la table des matières de la section

2.3.1 - Lancement du "shell" bash

Les fichiers de configuration utilisés par bash pour mettre en place la configuration d’un usager lorsque celui-ci se branche au système sont les suivants, dans l’ordre (évidemment, si un de ces fichiers n’existe pas, bash ne s’en préoccupe pas et passe au suivant):

  • d’abord, il lit /etc/profile, qui contient la configuration globale (à appliquer, à la base, à tous les usagers du système);
  • ensuite, il cherche dans l’ordre l’un des fichiers suivants, et utilise le premier qu’il trouve (et est capable de lire) pour mettre sur pied la configuration locale du login shell de l’usager: ~/.bash_profile, ~/.bash_login et ~/.profile (sur Ubuntu, le fichier utilisé est ~/.profile, puisque les autres n'existent pas. On voit souvent l'utilisation de ~/.bash_profile dans d'autres distributions).

Lorsque bash est sur le point de quitter (commande exit), il exécutera les commandes se trouvant dans le fichier ~/.bash_logout (si, bien sûr, il existe).

Par contre, au lancement d’un shell interactif (pas un login shell - donc un su), bash exécutera seulement le contenu du fichier ~/.bashrc et pas ceux de /etc/profile ou de ~/.bash_profile.  Ceci fait bien du sens puisque si vous utilisez su, c'est que vous vous êtes d'abord logué en mode login shell et que ces fichiers ont déjà été lus.

Notez qu'il est possible de forcer bash à se comporter différemment en lui spécifiant des options au lancement. Vous pouvez consulter man bash pour des détails si vous êtes curieux.

Retour à la table des matières de la section

2.3.2 - Que sont ces fichiers en fin de compte?

Les fichiers ~/.profile et ~/.bashrc et /etc/profile ne sont en fait rien d'autre que des scripts qui sont exécutés automatiquement au démarrage (et de façon à ce qu'ils soient exécutés dans le shell courant et pas dans un shell enfant, avec la commande source ou son équivalent, ".").  On peut les éditer comme on veut et les rendre aussi complexes que désiré.  Toutefois, la plupart du temps on se limitera à y définir des variables, les exporter et définir des alias.

Par convention, on placera normalement les définitions de variables dans ~/.profile et les définitions d'alias dans ~/.bashrc.  On demandera également à ~/.profile d'aller exécuter ~/.bashrc.  Pourquoi alors ne pas tout mettre dans ~/.profile?  Il y a une raison à ça, sauriez-vous l'expliquer?

Retour à la table des matières de la section

2.3.3 - En fin de compte, que se passe-t-il sur le système?

Officiellement, lorsque vous vous loguez en mode login shell (donc quand vous vous loguez normalement sur votre ordinateur), les deux fichiers qui sont automatiquement exécutés par bash sont /etc/profile et ~/.profile.  bash ne fait rien d'autre que d'exécuter ces deux scripts et vous placer dans votre répertoire maison.

Par contre en réalité d'autres fichiers sont lus.  Pourquoi?  Simplement parce que des commandes dans /etc/profile et ~/.profile demandent à bash de le faire.  Si ces commandes n'étaient pas placées là (et notez que leur présence n'est pas obligatoire, bien que recommandée), bash se bornerait à lire ses 2 fichiers et n'irait pas plus loin.

Tel qu'on l'a mentionné plus haut, une commande dans ~/.profile demande à bash d'exécuter ~/.bashrc.  De plus, une commande dans /etc/profile demande à bash d'aller exécuter /etc/bash.bashrc!  Donc concrètement, au login shell, ces quatre fichiers seront lus dans l'ordre:  /etc/profile, /etc/bash.bashrc, ~/.profile et ~/.bashrc.

Lorsque vous vous loguez en mode interactif (avec un su), bash ne lit que le ~/.bashrc

Notez que le ~/.bashrc va lire ~./bash_aliases s'il existe. On recommande de placer tous les alias à cet endroit pour éviter de jouer avec le ~/.bashrc dans ce cas mais ce n'est nullement obligatoire.

Retour à la table des matières de la section